const Menu = require('../models/menu');
const User = require('../models/user');
const Role = require('../models/role');

const fs = require('fs');
const path = require('path');


// 递归创建菜单及其子菜单
const createMenuRecursive = async (menuData, parentId = null, menuMap = new Map()) => {
    // 创建当前菜单
    const newMenu = new Menu({
        key: menuData.key,
        title: menuData.title,
        path: menuData.path,
        icon: menuData.icon,
        parentId: parentId,
        sort: menuData.sort,
        remark: menuData.remark,
        status: menuData.status,
        children: []
    });
    
    const savedMenu = await newMenu.save();
    menuMap.set(menuData.key, savedMenu._id);
    
    // 递归创建子菜单
    if (menuData.children && menuData.children.length > 0) {
        const childIds = [];
        for (const child of menuData.children) {
            const childId = await createMenuRecursive(child, savedMenu._id, menuMap);
            childIds.push(childId);
        }
        
        // 更新当前菜单的子菜单列表
        await Menu.findByIdAndUpdate(savedMenu._id, {
            $set: { children: childIds }
        });
    }
    
    return savedMenu._id;
}

// 初始化菜单数据
const initMenus = async () => {
    try {
        const count = await Menu.countDocuments();
        if (count > 0) {
            // 先删除再重新初始化
            await Menu.deleteMany({});
        }
        const menusData = JSON.parse(fs.readFileSync(path.join(__dirname, '../public/javascripts/default_menu.json'), 'utf8'));
            
        const menuMap = new Map();
        // 为顶级菜单创建条目
        for (const menu of menusData) {
            await createMenuRecursive(menu, null, menuMap);
        }
        return {
            code: 200,
            message: '初始化菜单数据成功'
        }
    } catch (error) {
        return {
            code: 500,
            message: '初始化菜单数据失败: ' + error.message
        }
    }
}


// 递归获取菜单结构
const buildMenuTree = async (menuIds) => {
    const menus = await Menu.find({ _id: { $in: menuIds } }).sort({ sort:1 });
    
    for (let menu of menus) {
        if (menu.children && menu.children.length > 0) {
            menu.children = await buildMenuTree(menu.children);
        }
    }
    
    return menus;
}

// 更新getAllMenus方法，返回树形结构
const getAllMenus = async () => {
    try {
        // 先获取顶级菜单
        const topMenus = await Menu.find({ parentId: null });
        const topMenuIds = topMenus.map(menu => menu._id);
        
        // 递归构建菜单树
        const menuTree = await buildMenuTree(topMenuIds);

        return {
            code: 200,
            data: menuTree,
            message: '获取菜单列表成功'
        }
    } catch (error) {
        return {
            code: 500,
            message: '获取菜单列表失败: ' + error.message
        }
    }
}
const createMenu = async (menuData) => {
    try {
        const newMenu = new Menu(menuData);
        const savedMenu = await newMenu.save();
        if(menuData.parentId) {
            await Menu.findByIdAndUpdate(menuData.parentId, {
                $push: { children: savedMenu._id }
            });
        }
        return {
            code: 200,
            data: savedMenu,
            message: '创建菜单成功'
        }
    } catch (error) {
        return {
            code: 400,
            message: '创建菜单失败: ' + error.message
        }
    }
}
const updateMenu = async (menuId, menuData) => {
    try {
        await Menu.findByIdAndUpdate(menuId, {
            $set: menuData
        });
        return {
            code: 200,
            message: '更新菜单成功'
        }
    } catch (error) {
        return {
            code: 400,
            message: '更新菜单失败: ' + error.message
        }
    }
}
const deleteMenu = async (menuId) => {
    try {
        await Menu.findByIdAndDelete(menuId);
        return {
            code: 200,
            message: '删除菜单成功'
        }
    } catch (error) {
        return {
            code: 400,
            message: '删除菜单失败: ' + error.message
        }
    }
}

const getRoleMenus = async (userId) => {
    try {
        const user = await User.findById(userId);
        if (!user) {
            return {
                code: 201,
                message: '用户不存在'
            }
        }

        const role = await Role.findOne({ _id: user.role });

        if (!role) {
            return {
                code: 201,
                message: '用户未分配角色'
            }
        }
        const menus =  role.isAdmin?await Menu.find({ status: true }).sort({ sort:1 }): await Menu.find({ _id: { $in: role.menus},status:true }).sort({ sort:1 }).lean();

        const newMenus = menus.map(menu => {
            return {
                id: menu._id,
                icon: menu.icon,
                parentId:menu.parentId,
                key: menu.key,
                title: menu.title,
                label: menu.title,
            };
        });
        const tree = buildMenuTreeOptimized(newMenus)
        
        return {
            code: 200,
            data: tree,
            message: '获取角色菜单成功'
        }
    } catch (error) {
        return {
            code: 500,
            message: '获取角色菜单失败: ' + error.message
        }
    }

}

function buildMenuTreeOptimized(menus) {
  const menuMap = {};
  
  // 首先将所有菜单项存入对象，以id为key
  menus.forEach(menu => {
    menuMap[menu.id] = { ...menu, children: [] };
  });
  
  const tree = [];
  Object.values(menuMap).forEach(menu => {
    // 检查parentId是否为null或undefined
    if (menu.parentId === null || menu.parentId === undefined) {
      tree.push(menu);
    } else {
      const parent = menuMap[menu.parentId];
      if (parent) {
        parent.children.push(menu);
      } else {
        // 记录无效的父菜单引用，但仍将其视为顶级菜单
        console.warn(`Menu ${menu.id} has invalid parentId ${menu.parentId}, treating as top-level`);
        tree.push(menu);
      }
    }
  });
  
  return tree;
}

module.exports = {
    getAllMenus,
    initMenus,
    createMenu,
    updateMenu,
    deleteMenu,
    getRoleMenus
}